package com.renchunlin.mytextview.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import com.renchunlin.mytextview.R

/*
 * class title: 
 * Author by RenChunLin, Email 18957806320@163.com, Date on 2021/6/15.
 * PS: Not easy to write code, please indicate.
 */

class NewTextView : View {

    //文字
    private var newTextViewText = ""

    //文字大小
    private var newTextViewTextSize = 15

    //文字颜色
    private var newTextViewTextColor = Color.BLACK

    //enum类型
    private val newTextViewInputType = "txt"

    //画笔
    private lateinit var mPaint: Paint

    //矩形边界
    private lateinit var bounds: Rect

    //构造函数会在代码里面new的时候调用
    //val newTextView=NewTextView(this)
    constructor(context: Context) : this(context, null)
    //在布局layout中使用（调用）
    /**
     * <com.renchunlin.mytextview.view.NewTextView
    app:layout_constraintTop_toTopOf="parent"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>
     */
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)

    //在布局layout中使用（调用），但是会有Style
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        /**
         * 自定义属性用来配置的 android:text="11111" 是系统的一个自定义属性
         */
        //获取自定定义属性
        val typeArray = context.obtainStyledAttributes(attrs, R.styleable.NewTextView)
        newTextViewText = typeArray.getString(R.styleable.NewTextView_newTextViewText).toString()
        newTextViewTextColor =
            typeArray.getColor(R.styleable.NewTextView_newTextViewTextColor, newTextViewTextColor)
        newTextViewTextSize = typeArray.getDimensionPixelSize(
            R.styleable.NewTextView_newTextViewTextSize,
            newTextViewTextSize
        )
        //回收
        typeArray.recycle()

        //初始化画笔
        mPaint = Paint()
        //设置画笔抗锯齿
        mPaint.isAntiAlias = true
        //设置字体大小
        mPaint.textSize = newTextViewTextSize.toFloat()
        //设置字体颜色
        mPaint.color = newTextViewTextColor
        //初始化矩形边界
        bounds = Rect()
    }

    /**
     * 自定义View的测量方法，测量布局的宽高的
     */
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        //布局的宽高都是由这个方法去指定
        //指定控件的宽高，需要测量
        //获取宽高的模式，用户在xml中设置的match_parent，wrap_content，或者固定值16dp
        val widthMode: Int = MeasureSpec.getMode(widthMeasureSpec)  //获取前面2位
        val heightMode: Int = MeasureSpec.getMode(heightMeasureSpec)
        //MeasureSpec.AT_MOST 在布局中指定了wrap_content
        //MeasureSpec.EXACTLY 在布局中指定了确切的值，比如100dp和match_parent fill_parent
        //MeasureSpec.UNSPECIFIED 这个模式我们很少用，尽可能的大,比如ListView，ScrollView 在测量子布局的时候会用UNSPECIFIED

        //widthMeasureSpec:包含两个信息是一个32位的值，第一个信息就是模式：前2位 第二个信息就是值：后30位

        //1.确定的值（xml宽高设置100dp等），这个时候不需要计算的，给的多少就是多少
        //2.给的是wrap_content 需要计算

        var widthSize = MeasureSpec.getSize(widthMeasureSpec) //获取后面30位
        //Log.i("chen", "宽度: $widthSize")
        var heightSize = MeasureSpec.getSize(heightMeasureSpec)
        //Log.i("chen", "宽度: $widthSize")

        if (widthMode == MeasureSpec.AT_MOST) {
            //计算的宽度 与字体的长度有关，与字体的大小有关，（文字用画笔来测量）
            /**
             * String text 要测量的文字
             * int start 开始测试的位置
             * int end 结束测试的位置
             * Rect bounds 矩形边界
             */
            //获取文本的Rect
            mPaint.getTextBounds(newTextViewText, 0, newTextViewText.length, bounds)
            /**
             * paddingLeft paddingRight 在xml设置padding
             */
            widthSize = bounds.width() + paddingLeft + paddingRight
            //Log.i("chen", "字体的宽度: $widthSize")
        }

        if (heightMode == MeasureSpec.AT_MOST) {
            mPaint.getTextBounds(newTextViewText, 0, newTextViewText.length, bounds)
            heightSize = bounds.height() + paddingTop + paddingBottom
            //Log.i("chen", "字体的高度: $widthSize")
        }

        //设置控件的宽高
        setMeasuredDimension(widthSize, heightSize)
    }

    /**
     * 用于绘制
     */
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        //画文本
        //canvas.drawText()
        //画弧
        //canvas.drawArc()
        //画圆
        //canvas.drawCircle()

        /**
         * 画文字
         *  String text 要画的文字
         *  float x 正在绘制的文本原点的 x 坐标
         *  float y 正在绘制的文本基线的 y 坐标
         */

        //获取文本的Rect
        mPaint.getTextBounds(newTextViewText, 0, newTextViewText.length, bounds)
        //计算baseline
        val fontMetrics = mPaint.fontMetrics
        val distance = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom
        val x = width / 2 - bounds.width() / 2
        //dy 代表的是：高度的一半到 baseLine的距离
        val dy = height / 2 + distance
        canvas.drawText(newTextViewText, x.toFloat(), dy, mPaint)
        Log.i("chen", "width: $width")
        Log.i("chen", "bounds_width: ${bounds.width()}")
        Log.i("chen", "width/2: ${width / 2}")
    }

    /**
     * 处理跟用户交互的，手指触摸，事件分发，事件拦截
     */
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when (event?.action) {
            MotionEvent.ACTION_UP -> {
                //手指抬起
            }

            MotionEvent.ACTION_DOWN -> {
                //手指按下
            }

            MotionEvent.ACTION_MOVE -> {
                //手指移动
            }
        }
        return super.onTouchEvent(event)

    }
}